import 'package:demo/common/utils/log_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';

/// 详细用法 https://juejin.cn/post/7026150456673959943#heading-6
class DialogUtil {
  static init() {
    SmartDialog.config.custom = SmartConfigCustom(
      backDismiss: false,
      clickMaskDismiss: false,
      backType: SmartBackType.block,
      maskColor: Colors.black.withValues(alpha: 0.9),
      alignment: Alignment.center,
      bindPage: true, //绑定页面
    );

    SmartDialog.config.toast = SmartConfigToast(alignment: Alignment.center);

    // 禁止交互
    EasyLoading.instance.userInteractions = false;
  }

  static Future<void> dismiss({String? tag, SmartStatus status = SmartStatus.dialog}) async {
    await SmartDialog.dismiss(tag: tag, status: status);
  }

  static void showToast(String text) {
    SmartDialog.showToast(text);
  }

  static Future<void> showLoading() async {
    // SmartDialog.showLoading(msg: "");
    await EasyLoading.show();
  }

  static Future<void> dismissLoading() async {
    // SmartDialog.dismiss(status: SmartStatus.loading);
    await EasyLoading.dismiss();
  }
}

/// 将widget 扩展为可以显示dialog
/// todo enableOnBackInvokedCallback="true"预测返回开启时会导致backDismiss失效
/// todo 已提issues https://github.com/fluttercandies/flutter_smart_dialog/issues/279
extension ExDialog on Widget {
  Future showDialog({
    VoidCallback? onDismiss,
    bool? backDismiss,
    bool? clickMaskDismiss,
    Color? maskColor,
    Alignment? alignment,
    BuildContext? bindWidget,
    String? tag,
    bool? useSystem,
  }) {
    return SmartDialog.show(
      backDismiss: backDismiss,
      clickMaskDismiss: clickMaskDismiss,
      maskColor: maskColor,
      alignment: alignment,
      bindWidget: bindWidget,
      tag: tag,
      useSystem: useSystem,
      onDismiss: onDismiss,
      builder: (context) {
        return this;
      },
    );
  }

  Future showAttach({
    required BuildContext? targetContext,
    var attachAlignmentType = SmartAttachAlignmentType.center,
    backDismiss = true,
    clickMaskDismiss = true,
    alignment = Alignment.center,
    String? tag,
    bool? useSystem,
    Color? maskColor,
    bool? usePenetrate = true,
  }) {
    SmartDialog.config.attach = SmartConfigAttach(attachAlignmentType: attachAlignmentType);
    return SmartDialog.showAttach(
      targetContext: targetContext,
      backDismiss: backDismiss,
      clickMaskDismiss: clickMaskDismiss,
      alignment: alignment,
      tag: tag,
      useSystem: useSystem,
      maskColor: maskColor,
      usePenetrate: usePenetrate,
      builder: (context) {
        return this;
      },
    );
  }
}

// 包含权重和时间戳的对话框项
class DialogItem {
  final Widget dialog;
  final int weight;
  final DateTime timestamp; // 新增时间戳字段
  final BuildContext? bindWidget;
  final Color? maskColor;
  final bool? backDismiss;
  final bool? clickMaskDismiss;
  final VoidCallback? onDismiss;

  DialogItem(
    this.dialog,
    this.weight, {
    this.bindWidget,
    this.maskColor,
    this.backDismiss,
    this.clickMaskDismiss,
    this.onDismiss,
  }) : timestamp = DateTime.now(); // 自动记录创建时间
}

/// 用来连续显示dialog
/// 先按权重高的优先显示
/// 再按先加入的优先显示
/// 测试案例 结果 5-1-3-2-4
/// dialogList.add(
///   GestureDetector(
///     onTap: DialogUtil.dismiss,
///     child: Container(color: Colors.yellow, width: 100, height: 100, child: Text("1")),
///   ),
/// );
/// dialogList.add(
///   GestureDetector(
///     onTap: DialogUtil.dismiss,
///     child: Container(color: Colors.yellow, width: 100, height: 100, child: Text("2")),
///   ),
///   weight: 88,
/// );
/// dialogList.add(
///   GestureDetector(
///     onTap: DialogUtil.dismiss,
///     child: Container(color: Colors.yellow, width: 100, height: 100, child: Text("3")),
///   ),
///   weight: 99,
/// );
/// dialogList.add(
///   GestureDetector(
///     onTap: DialogUtil.dismiss,
///     child: Container(color: Colors.yellow, width: 100, height: 100, child: Text("4")),
///   ),
///   weight: 88,
/// );
/// dialogList.add(
///   GestureDetector(
///     onTap: DialogUtil.dismiss,
///     child: Container(color: Colors.yellow, width: 100, height: 100, child: Text("5")),
///   ),
///   force: true,
/// );
class DialogList {
  final List<DialogItem> _dialogQueue = [];

  void add(
    Widget dialog, {
    VoidCallback? onDismiss,
    int weight = 0,
    bool force = false, //强制覆盖显示
    BuildContext? bindWidget,
    bool? backDismiss,
    bool? clickMaskDismiss,
    Color? maskColor,
  }) {
    final dialogItem = DialogItem(
      dialog,
      weight,
      onDismiss: onDismiss,
      bindWidget: bindWidget,
      backDismiss: backDismiss,
      clickMaskDismiss: clickMaskDismiss,
      maskColor: maskColor,
    );
    _dialogQueue.add(dialogItem);

    // 双重排序：先按权重降序，再按时间戳升序
    _dialogQueue.sort((a, b) {
      final weightCompare = b.weight.compareTo(a.weight);
      return weightCompare != 0 ? weightCompare : a.timestamp.compareTo(b.timestamp);
    });

    if (force) {
      // 强制显示 排在第一个才会继续显示下一个
      _showDialog(dialogItem, showNext: _dialogQueue.length == 1);
    } else if (_dialogQueue.length == 1) {
      _showDialog(_dialogQueue.first);
    }
  }

  void _showDialog(DialogItem dialogItem, {bool showNext = true}) {
    dialogItem.dialog.showDialog(
      bindWidget: dialogItem.bindWidget,
      maskColor: dialogItem.maskColor,
      backDismiss: dialogItem.backDismiss,
      clickMaskDismiss: dialogItem.clickMaskDismiss,
      onDismiss: () {
        dialogItem.onDismiss?.call();
        // 关闭后从队列删除
        _dialogQueue.remove(dialogItem);
        if (_dialogQueue.isNotEmpty && showNext) {
          _showDialog(_dialogQueue.first);
        }
      },
    );
  }

  /// 清除队列 可取消后续弹窗显示
  void clear() {
    _dialogQueue.clear();
  }
}

/// 函数前后加上loading
void loadingScope(Function() block, {Function(Object e)? onError}) async {
  try {
    DialogUtil.showLoading();
    await block();
  } catch (e, st) {
    onError?.call(e);
    Log.h(e, stackTrace: st);
  } finally {
    DialogUtil.dismissLoading();
  }
}
